MALLOC(3) | Linux Programmer's Manual | MALLOC(3) |
名前¶
calloc, malloc, free, realloc - 動的なメモリの割り当てと解放を行う
書式¶
#include <stdlib.h> void *calloc(size_t nmemb, size_t size);
void *malloc(size_t size);
void free(void *ptr);
void *realloc(void *ptr, size_t size);
説明¶
calloc() は size バイトの要素 nmemb 個からなる配列にメモリを割り当て、 割り当てられたメモリに対するポインタを返す。 メモリの内容は数値ゼロ (全ビットがゼロのバイト) にセットされる。 nmemb か size が 0 の場合、 calloc() は NULL または free() に後で渡しても問題の起こらない一意なポインタ値を返す。
malloc() は size バイトを割り当て、 割り当てられたメモリに対するポインタを返す。 メモリの内容はクリアされない。 size が 0 の場合、 malloc() は NULL または free() に後で渡しても問題の起こらない一意なポインタ値を返す。
free() はポインタ ptr が指すメモリ空間を解放する。このポインタは、以前に呼び出された malloc(), calloc(), realloc() のいずれかが返した値でなければならない。 これ以外のポインタを指定したり、すでに free(ptr) が実行されていたりした場合の動作は定義されていない。 ptr が NULL の場合には、なんの動作も行われない。
realloc() は、ポインタ ptr が示すメモリブロックのサイズを変更して size バイトにする。 新旧のサイズのうち、小さいほうのブロックに含まれる内容は変更されない。 新しく割り当てられたメモリの内容は初期化されない。 size がどの値であっても、 ptr が NULL の場合には malloc(size) と等価である。 size が 0 で ptr が NULL でない場合には、 free(ptr) と等価である。 ptr が NULL 以外の場合、 ptr は以前に呼び出された malloc(), calloc(), realloc() のいずれかが返した値でなければならない。 ptr が指す領域が移動されていた場合は free(ptr) が実行される。
返り値¶
calloc() と malloc() は、割り当てられたメモリへのポインタを返す。 割り当てられたメモリは、あらゆる種類の変数に対応できるように アラインメントされている。 エラーの場合、これらの関数は NULL を返す。 size が 0 で呼び出した malloc() や、 nmemb か size が 0 で呼び出した calloc() が成功した場合にも NULL が返される。
free() は値を返さない。
realloc() は新たに割り当てられたメモリへのポインタを返す。 これはあらゆる種類の変数に対応できるようにアラインメントされており、 ptr とは異なることもある。 割り当て要求に失敗した場合は NULL が返る。 size が 0 の場合には、NULL もしくは free() に渡すことができるポインタが返る。 realloc() が失敗した場合には、元のブロックは変更されない。 つまり、解放されたり移動されたりはしない。
準拠¶
C89, C99.
注意¶
通常、 malloc() は、ヒープからメモリを割り当て、必要に応じてヒープのサイズを sbrk(2) を使って調節する。 MMAP_THRESHOLD バイトよりも大きなメモリブロックを割り当てる場合、 glibc の malloc() 実装は mmap(2) を使ってプライベートな無名マッピング (anonymous mapping) として メモリを割り当てる。 デフォルトでは MMAP_THRESHOLD は 128 kB だが、 mallopt(3) を使って調整できる。 mmap(2) を使って行われたメモリ割り当ては RLIMIT_DATA リソース上限の影響を受けない (getrlimit(2) 参照)。
Unix98 標準では、 malloc(), calloc(), realloc() は実行に失敗したときに errno を ENOMEM に設定することになっている。 Glibc ではこれが守られていることを仮定している (またこれらのルーチンの glibc バージョンはこのことを守っている)。 個人的に別の malloc の実装を使っていて、その malloc が errno を設定しない場合には、失敗した際に errno にエラーの理由を設定しないライブラリルーチンがあるかもしれない。
malloc(), calloc(), realloc(), free() における事故は、 ほとんどの場合はヒープの破壊 (corruption) が原因である。 例えば、割り当てられた領域をオーバーフローする、 同じポインタに二度 free する、などがこれにあたる。
最近のバージョンの Linux libc (5.4.23 以降) と glibc (2.x) では、 malloc() の動作を環境変数によって制御できるような実装がされている。 MALLOC_CHECK_ が設定されていると、特殊な実装が用いられ、 単純なエラーには耐えることができるようになる (効率は悪くなる)。例えば、 free() を同じ引き数で二度呼び出してしまう、 1 バイトだけ行きすぎてしまう (off-by-one バグ) などがこれに当たる。 しかし、これらのエラーの全てを防ぐことができるわけではなく、 その場合にはメモリリークが起こってしまう。 MALLOC_CHECK_ が 0 にセットされていると、ヒープの破壊を黙って無視する。 1 にセットされていると、診断メッセージが標準エラー出力に表示される。 2 にセットされていると、ただちに abort(3) が呼び出される。 3 にセットされていると、診断メッセージが標準エラー出力に表示され、 プログラムは強制終了 (abort) される。 MALLOC_CHECK_ に 0 以外の値をセットして役に立つ状況としては、 実際のプロセスのクラッシュがずっと後に起こり、 本当の原因を探し出すのが非常に困難な場合などが挙げられるだろう。
バグ¶
デフォルトでは、Linux
は楽観的メモリ配置戦略を用いている。
つまり、 malloc() が NULL
でない値を返しても、そのメモリが実際に利用可能であることが
保証されない。これは本当にまずいバグである。
システムがメモリ不足状態になったとき、悪名高いメモリ不足解決器
(OOM killer)
によって一つまたは複数のプロセスが削除される。
突然あるプロセスが削除されるのが望ましくない状況で使用されていて、
しかもカーネルのバージョンが十分に最近のものであれば、このメモリを
割り当て過ぎる動作
(overcommitting behavior)
を以下のコマンドで
無効にできる。
# echo 2 > /proc/sys/vm/overcommit_memory
カーネルの付属文書の vm/overcommit-accounting と sysctl/vm.txt も参照のこと。
関連項目¶
2009-01-13 | GNU |